﻿using System;

namespace Cloak.Mvvm.Bindings
{
	/// <summary>
	/// A binding between a source object and a view model
	/// </summary>
	public abstract class ViewModelBinding : IViewModelBinding
	{
		private bool _isModified;

		#region IViewModelBinding
		/// <summary>
		/// Gets whether the view model's data differs from the source data
		/// </summary>
		public bool IsModified
		{
			get { return _isModified; }
			protected set
			{
				if(value != _isModified)
				{
					_isModified = value;

					OnIsModifiedChanged(EventArgs.Empty);
				}
			}
		}

		/// <summary>
		/// Occurs when the value of the <see cref="IsModified"/> property changes
		/// </summary>
		public event EventHandler IsModifiedChanged;

		/// <summary>
		/// Raises the <see cref="IsModifiedChanged"/> event
		/// </summary>
		protected virtual void OnIsModifiedChanged(EventArgs e)
		{
			var handler = IsModifiedChanged;

			if(handler != null)
			{
				handler(this, e);
			}
		}

		/// <summary>
		/// Reads from the source object and sets values on the view model
		/// </summary>
		public void BindFromSource()
		{
			BindFromSourceCore();

			IsModified = false;
		}

		/// <summary>
		/// Reads from the view model and sets values on the source object
		/// </summary>
		public void BindToSource()
		{
			BindToSourceCore();

			IsModified = false;
		}
		#endregion

		/// <summary>
		/// When implemented by a derived class, reads from the source object and sets values on the view model
		/// </summary>
		protected abstract void BindFromSourceCore();

		/// <summary>
		/// When implemented by a derived class, reads from the view model and sets values on the source object
		/// </summary>
		protected abstract void BindToSourceCore();
	}
}